<?php

namespace common\models;

use Yii;
use yii\db\Expression;
use yii\helpers\ArrayHelper;
use common\helpers\Util;
use common\helpers\Render;
use common\helpers\Uploader;

/**
 * This is the model class for table "User".
 */
class User extends ActiveRecord {

    // 芝麻信用分部分免额度上限
    const BondAlipayScoreLimit = 1500;
    
    // User's role defined
    const RoleDesigner = 0;
    const RoleEmployer = 1;
    public static $roleSelector = [
        self::RoleDesigner => ['title' => '设计师', 'status' => 'blue'],
        self::RoleEmployer => ['title' => '雇主', 'status' => 'orange'],
    ];

    // 注册来源
    const RegistorOuter = 0;
    const RegistorInner = 1;
    public static $registorSelector = [
        self::RegistorOuter => ['title' => '外部', 'status' => 'blue'],
        self::RegistorInner => ['title' => '内部', 'status' => 'purple'],
    ];

    // 用户等级
    const LevelD = 0;
    const LevelC = 1;
    const LevelB = 2;
    const LevelA = 3;
    const LevelS = 4;
    public static $levelSelector = [
        self::LevelD => ['title' => '游刃有余', 'status' => 'gray'],
        self::LevelC => ['title' => '炉火纯青', 'status' => 'orange'],
        self::LevelB => ['title' => '技压群雄', 'status' => 'blue'],
        self::LevelA => ['title' => '出神入化', 'status' => 'green'],
        self::LevelS => ['title' => '登峰造极', 'status' => 'red'],
    ];

    const StatusPending = 0;
    const StausAlipay  = 1;
  	const StausLevel  = 2;
    // const StatusActivation = 1;
    const StatusActive = 10;
    public static $statusSelector = [
        self::StatusPending => ['title' => '未提交资料', 'status' => 'red'],
        self::StausAlipay => ['title' => '芝麻信用等级审核', 'status' => 'red'],
      	self::StausLevel => ['title' => '保证金缴纳审核', 'status' => 'purple'],
        // self::StatusActivation => ['title' => '激活中', 'status' => 'purple'],
        self::StatusActive => ['title' => '已激活', 'status' => 'green'],
    ];
    
    // 性别
    const GenderSecrecy = 0;
    const GenderMale = 1;
    const GenderFemale = 2;
    public static $genderSelector = [
        self::GenderSecrecy => ['title' => '保密', 'status' => 'gray'],
        self::GenderMale => ['title' => '男', 'status' => 'blue'],
        self::GenderFemale => ['title' => '女', 'status' => 'red'],
    ];
    
    // 工作年限
    const WorkLifeFirst = 1;
    const WorkLifeSecond = 2;
    const WorkLifeThird = 3;
    const WorkLifeFourth = 4;
    const WorkLifeFifth = 5;
    const WorkLifeSxth = 6;
    public static $workLifeSelector = [
        self::WorkLifeFirst => ['title' => '1~2年', 'status' => 'gray'],
        self::WorkLifeSecond => ['title' => '2~3年', 'status' => 'orange'],
        self::WorkLifeThird => ['title' => '3~4年', 'status' => 'blue'],
        self::WorkLifeFourth => ['title' => '4~5年', 'status' => 'green'],
        self::WorkLifeFifth => ['title' => '5~6年', 'status' => 'purple'],
        self::WorkLifeSxth => ['title' => '6年以上', 'status' => 'red'],
    ];
    
    // Bond's type
    const BondStatusMoney = 1;
    const BondStatusAlipay = 2;
    public static $bondStatusSelector = [
        self::BondStatusMoney => ['title' => '保证金', 'status' => 'green'],
        self::BondStatusAlipay => ['title' => '蚂蚁信用分', 'status' => 'blue'],
    ];
    
    // only define rules for those attributes that
    // will receive user inputs.
    public function rules()
    {
        // 'nickname', 'realname', 'id_number', 'email', 'alipay', 'wechat', 'birthday',
        return [
            [['username', 'password_digest', 'role', 'mobile'], 'required'],
            [['role', 'level', 'gender', 'salary_level', 'salary', 'registor', 'salary_level', 'work_life', 'alipay_score', 'bond_status'], 'integer'],
            [['username', 'password_digest', 'alipay', 'photo', 'wechat', 'face_photo', 'wechat_qrcode'], 'string', 'max' => 64],
            [['mobile'], 'match', 'pattern' => "/^1\d{10}$/"],
            [['email'], 'string', 'max' => 64],
            [['nickname', 'realname', 'birthday', 'qq'], 'string', 'max' => 16],
            [['id_number', 'skills', 'tags'], 'string', 'max' => 32],
            [['activation_code'], 'string', 'length' => 6],
            [['address'], 'string', 'max' => 128],
            [['describe'], 'string', 'max' => 255],
            [['star'], 'double'],
            [['username', 'mobile', 'id_number'], 'unique'],
        ];
    }
    /**
     * 字段名称
     * @return array
     */
    public function attributeLabels()
    {
        return [
            'username' => '用户名',
            'password_digest' => '密码',
            'role' => '角色',
            'mobile' => '手机号',
            'email' => '邮箱',
            'alipay' => '支付宝账号',
            'wechat' => '微信',
            'qq' => 'QQ',
            'wechat_qrcode' => '微信二维码',
            'nickname' => '昵称',
            'realname' => '姓名',
            'alipay_score' => '芝麻信用分',
            'bond_status' => '保证金状态',
            'id_number' => '身份证号',
            'face_photo' => '正面照',
            'photo' => '头像',
            'gender' => '性别',
            'work_life' => '工作年限',
            'birthday' => '生日',
            'address' => '居住地',
            'level' => '设计师等级',
            'salary_level' => '期望月薪',
            'salary' => '月薪',
            'registor' => '注册类型',
            'skills' => '擅长软件',
            'tags' => '标签',
            'star' => '星级',
            'describe' => '个人评价',
        ];
    }
    /**
     * update & insert data check config
     * @param $type string 数据操作校验类型
     * @param $encodeJson boolean 是否转成json串
     * @return array
     */
    public static function flyer($type = 'update')
    {
        if($type == 'ensume') {
            return [
                'param' => [
                    'salary' => ['月薪', ['int', 'get' => 0, 'required']],
                    // 'activation_code' => ['激活码', ['length' => 6, 'required']],
                ]
            ];
        }
      	if($type == 'alipayscore') {
            return [
                'param' => [
                    'alipay_score' => ['芝麻信用分', ['int', 'get' => 0, 'required']],
                ]
            ];
        }
        if($type == 'information') {
            return [
                'param' => [
                    'nickname' => ['昵称', ['maxlength' => 16, 'required']],
                    'email' => ['邮箱', 'email'],
                    'alipay' => ['支付宝', ['maxlength' => 64, 'required']],
                    'wechat' => ['微信', ['maxlength' => 64, 'required']],
                    'wechat_qrcode' => ['微信二维码'],
                    'qq' => ['QQ', ['int', 'minlength' => 4, 'maxlength' => 16]],
                    'realname' => ['姓名', ['maxlength' => 16, 'required']],
                    'id_number' => ['身份证', ['idcard', 'required']],
                    'face_photo' => ['手持身份证正面照'],
                    'gender' => ['性别', ['inkey' => static::$genderSelector, 'required']],
                    'work_life' => ['工作年限', ['maxlength' => 16]],
                    'birthday' => ['生日', ['date' => 'Y-m-d', 'required']],
                    'address' => ['居住地', ['maxlength' => 128]],
                    'skills' => ['擅长软件', ['maxlength' => 32]],
                    'tags' => ['标签', ['maxlength' => 32]],
                    'describe' => ['个人描述', ['maxlength' => 128]],
                ],
            ];
        }
        if($type == 'informationt') {
            return [
                'param' => [
                    'nickname' => ['昵称', ['maxlength' => 16, 'required']],
                    'qq' => ['QQ', ['int', 'minlength' => 4, 'maxlength' => 16]],
                    'work_life' => ['工作年限', ['maxlength' => 16]],
                    'skills' => ['擅长软件', ['maxlength' => 32]],
                    'tags' => ['标签', ['maxlength' => 32]],
                    'describe' => ['个人描述', ['maxlength' => 128]],
                ],
            ];
        }
      	if($type == 'verificationgrade') {
            return [
                'param' => [
                    'level' => ['设计师等级', ['inkey' => User::$levelSelector, 'required']],
                ]
            ];
        }
        if($type == 'employer-information') {
            return [
                'param' => [
                    'nickname' => ['昵称', ['maxlength' => 16, 'required']],
                    'email' => ['邮箱', 'email'],
                    'alipay' => ['支付宝', ['maxlength' => 64]],
                    'wechat' => ['微信', ['maxlength' => 64]],
                    'qq' => ['QQ', ['int', 'minlength' => 4, 'maxlength' => 16]],
                    'realname' => ['姓名', ['maxlength' => 16,'required']],
                    'id_number' => ['身份证', ['idcard']],
                    'gender' => ['性别', ['inkey' => static::$genderSelector]],
                    'birthday' => ['生日', ['date' => 'Y-m-d']],
                    'address' => ['居住地', ['maxlength' => 128]],
//                    'captcha' => ['验证码', ['int', 'length' => 6,'required']],
                ],
            ];
        }
    }
    /**
     * before save model
     * @param $insert array 保存数组
     * @return boolean
     */
    public function beforeSave($insert)
    {
        // 插入前
        if(parent::beforeSave($insert)) {
            // 添加/修改 用户
            $this->hashPassword();
        }
        return true;
    }
    // 生成加密密码
    // @describe create md5 password and set it to password_digest
    public function hashPassword()
    {
        if($this->password_digest == $this->getOldAttribute('password_digest')) {
            return true;
        }
        $this->password_digest = static::passwordDigest($this->password_digest);
        return true;
    }
    /**
     * create md5 password
     * @param $password string 密码
     * @return string md5串
     */
    public static function passwordDigest($password)
    {
        return password_hash($password.Yii::$app->params['userPasswordDigest'], PASSWORD_DEFAULT, ['cost' => 13]);
    }

    /**
     * check wether this admin password right
     * @return boolean
     */
    public function validatePassword($password)
    {
        return password_verify($password.Yii::$app->params['userPasswordDigest'], $this->password_digest);
    }

    /**
     * check wthere current user was designer
     * @return boolean
     */
    public function designer()
    {
        return $this->role == static::RoleDesigner ? true : false;
    }
    /**
     * check wthere current user was designer
     * @return boolean
     */
    public function employer()
    {
        return $this->role == static::RoleEmployer ? true : false;
    }
    /**
     * given the controller name by user's role type
     * @return string
     */
    public function controller()
    {
        if($this->designer()) {
            return 'designer';
        }
        return 'employer';
    }
    
    /**
     * 判断是否内部用户
     * @return boolean
     */
    public function inner()
    {
        return in_array($this->registor, [static::RegistorInner]) ? true : false;
    }

    /**
     * check wether this admin was out of time
     * @return boolean
     */
    public function valid()
    {
        if($this->deleted()) {
            return false;
        }
        return true;
    }
    /**
     * check wether this user was out validate
     * @return boolean
     */
    public static function isValid($user)
    {
        if(empty($user)) {
            return false;
        }
        if($user->deleted_at > 0) {
            return false;
        }
        return true;
    }
    
    /**
     * 判断用户资料是否完善
     * @param $verify boolean 是否校验审核状态
     * @return boolean
     */
    public function information($verify = false)
    {
        if($verify) {
            if( ! in_array($this->status, [static::StatusActive])) {
                return false;
            }
        }
        return empty($this->realname) ? false : true;
    }
    /**
     * 校验是否可以找工作
     * @return boolean
     */
    public function active()
    {
        if( ! $this->valid()) {
            return false;
        }
        if( ! $this->information(true)) {
            return false;
        }
        // 用户状态
        if( ! in_array($this->status, [static::StatusActive])) {
            return false;
        }
        // 保证金状态
        if( ! $this->bond()) {
            return false;
        }
        return true;
    }
    /**
     * 芝麻信用等级验证状态
     * @return boolean
     */
    public function verificationgrade()
    {
      	if($this->status == 1){
            return false;
        }
        return true;
    }
    public function grade()
    {
        if($this->status == 2){
            return false;
        }
        return true;
    }
    /**
     * 保证金状态
     * @return boolean
     */
//    public function grade()
//    {
//        if( ! in_array($this->status, [static::StausAlipay])) {
//            return false;
//        }
//        return true;
//    }
//    public function gradestaus()
//    {
//        if( ! in_array($this->status, [static::StausLevel])) {
//            return false;
//        }
//        return true;
//    }

    /**
     * 判断用户缴纳保证金状态
     * @return boolean
     */
    public function bond()
    {
        // 保证金状态
        if( ! in_array($this->bond_status, [static::BondStatusMoney, static::BondStatusAlipay])) {
            return false;
        }
        return true;
    }
    
    /**
     * 设置保证金状态
     * @return boolean
     */
    public function setBond($type)
    {
        if( ! array_key_exists($type, static::$bondStatusSelector)) {
            return false;
        }
        $this->bond_status = $type;
        $this->status = self::StatusActive;
        $this->updated_at = time();
        return $this->save();
    }
    
    /**
     * 注册用户
     * @return boolean
     */
    public function tregister()
    {
        return $this->transaction(function($db) {
            if( ! $this->save()) {
                throw new \Exception('init user error');
            }
            if( ! $this->initAccount()) {
                throw new \Exception('init user account error');
            }
            return true;
        });
    }
    /**
     * 获取邀请人信息
     * @return ActiveRecord
     */
    public function getInvitor()
    {
        return $this->hasOne(User::className(), ['inviter' => 'id']);
    }
    /**
     * 设置登陆态
     * @return boolean
     */
    public function login()
    {
        $cache = $this->attributes;
        return Yii::$app->session->set('user', $cache);
    }
    
    /**
     * 会员登出
     * @return boolean
     */
    public function logout()
    {
        Yii::$app->user = null;
        return Yii::$app->session->remove('user');
    }

    /**
     * 初始化账户信息
     * @return \yii\db\ActiveQuery
     */
    public function initAccount()
    {
        return UserAccount::initAccount($this->id);
    }
    
    /**
     * 获取账户信息
     * @return \yii\db\ActiveQuery
     */
    public function getAccount()
    {
        return $this->hasOne(UserAccount::className(), ['user_id' => 'id']);
    }

    /**
     * 获取用户优惠劵
     * @return \yii\db\ActiveQuery
     */
    public function getCoupons()
    {
        return $this->hasMany(UserCoupon::className(), ['user_id' => 'id']);
    }
    
    /**
     * 获取用户登录信息
     * @return \yii\db\ActiveQuery
     */
    public function getLogins($limit = 10)
    {
        return $this->hasMany(UserLogin::className(), ['user_id' => 'id'])->limit($limit);
    }

    /**
     * 获取单个用户受教育经历
     * @return \yii\db\ActiveQuery
     */
    public function getEducation()
    {
        return $this->hasOne(UserEducation::className(), ['user_id' => 'id']);
    }
    /**
     * 获取用户受教育经历
     * @return \yii\db\ActiveQuery
     */
    public function getEducations()
    {
        return $this->hasMany(UserEducation::className(), ['user_id' => 'id']);
    }

    /**
     * 获取用户工作经历
     * @return \yii\db\ActiveQuery
     */
    public function getJobs()
    {
        return $this->hasMany(UserJob::className(), ['user_id' => 'id']);
    }

    /**
     * 获取用户作品列表
     * @param $offset int 搜索开始位置
     * @param $limit int 搜索条数
     * @return \yii\db\ActiveQuery
     */
    public function getDesigns($offset = 0, $limit = 20)
    {
        return $this->hasMany(Design::className(), ['user_id' => 'id'])->offset($offset)->limit($limit);
    }
    
    /**
     * 获取用户的评价
     * @return array
     */
    public function getEvaluates()
    {
        return $this->hasMany(UserEvaluate::className(), ['user_id' => 'id']);
    }
    
    /**
     * 根据用户的评价记录计算用户的星级
     * @return boolean
     */
    public function calculateStar()
    {
        $this->star = UserEvaluate::find()
            ->select('sum(`communicate` + `originality` + `efficiency` + `major`) DIV (count(1) * 4)')
            ->where(['user_id' => $this->id])->scalar();
        if( ! $this->star) {
            $this->star = UserEvaluate::StartLimit;
        }
        $this->updated_at = time();
        return $this->save();
    }

    /**
     * 获取用户技能
     * @return \yii\db\ActiveQuery
     */
//    public function getSkills()
//    {
//        return $this->hasMany(UserSkill::className(), ['user_id' => 'id']);
//    }

    /**
     * 获取用户上传列表
     * @param $type int 上传类型
     * @return \yii\db\ActiveQuery
     */
    public function getUploads($type = UserUpload::TypeDesign)
    {
        return $this->hasMany(UserUpload::className(), ['user_id' => 'id'])->andWhere(['type' => $type]);
    }
    /**
     * 上传图片
     * @param $name string file名称
     * @param $type int 上传类型
     * @return boolean 
     */
    public function saveUploads($name, $type = UserUpload::TypeDesign)
    {
        $configurate = require Yii::getAlias('@common/config/uploader.php');
        $userUploads = $this->getUploads($type)->all();
        for($index = 0; $index < 9; ++$index) {
            $name = 'design'.$index;
            // 删除当前的上传文件
            if(empty($_FILES[$name])) {
                if(isset($userUploads[$index])) {
                    $userUploads[$index]->delete();
                }
                continue;
            }
            // 开始上传图片
            $loader = (new Uploader($configurate['designerUpload']))->upload($name);
            if($loader['code'] == SuccessCode) {
                if(isset($userUploads[$index])) {
                    $uploader = $userUploads[$index];
                    // 删除当前已上传的文件
                    Util::trashUpload($uploader->image);
                }
                else {
                    $uploader = new UserUpload();
                    $uploader->user_id = $this->id;
                    $uploader->type = $type;
                }
                $uploader->image = $loader['path'];
                $uploader->save();
            }
        }
        return true;
    }

    /**
     * 删除用户上传的记录、文件
     * @param $type int 上传类型
     * @return boolean
     */
    public function trashUploador($type = '')
    {
        foreach($this->getUploads($type)->all() as $upload) {
            $upload->delete();
        }
        return true;
    }

    /**
     * 获取用户收藏记录
     * @return \yii\db\ActiveQuery
     */
    public function getCollections()
    {
        return $this->hasMany(UserCollection::className(), ['user_id' => 'id']);
    }
    
    /**
     * 获取投递简历信息
     * @param $offset integer 搜索位置
     * @param $limit integer 数量
     * @return \yii\db\ActiveQuery
     */
    public function getRecruitApplicants($offset = 0, $limit = 10)
    {
        return $this->hasMany(RecruitApplicant::className(), ['designer_id' => 'id'])
            ->with('recruit')->offset($offset)->limit($limit)->all();
    }
    
    /**
     * 获取用户擅长类目
     * @return \yii\db\ActiveQuery
     */
    public function getCategories($type = UserCategory::TypeCategory)
    {
        return $this->hasMany(UserCategory::className(), ['user_id' => 'id'])->andWhere(['type' => $type]);
    }
    // 数组形式
    public function getCategoriesArray()
    {
        return ArrayHelper::getColumn($this->categories, 'category_id');
    }
    // 字符串形式`,`分割
    public function getCategoriesString()
    {
        return implode(',', $this->getCategoriesArray());
    }
    /**
     * 获取用户擅长类型
     * @return \yii\db\ActiveQuery
     */
    public function getModels()
    {
        return $this->getCategories(UserCategory::TypeModel);
    }
    // 数组形式
    public function getModelsArray()
    {
        return ArrayHelper::getColumn($this->models, 'category_id');
    }
    // 字符串形式`,`分割
    public function getModelsString()
    {
        return implode(',', $this->getModelsArray());
    }
    /**
     * 获取用户擅长风格
     * @return \yii\db\ActiveQuery
     */
    public function getStyles()
    {
        return $this->getCategories(UserCategory::TypeStyle);
    }
    // 数组形式
    public function getStylesArray()
    {
        return ArrayHelper::getColumn($this->styles, 'category_id');
    }
    // 字符串形式`,`分割
    public function getStylesString()
    {
        return implode(',', $this->getStylesArray());
    }
    /**
     * 保存用户分类
     * @param $name string checkbox名称
     * @param $type int 上传类型
     * @return boolean 
     */
    public function saveCategories($categories, $type = UserCategory::TypeCategory)
    {
        $userCategories = ArrayHelper::index($this->getCategories($type)->all(), 'category_id');
        foreach($categories as $id) {
            if(isset($userCategories[$id])) {
                unset($userCategories[$id]);
            }
            else {
                $category = new UserCategory();
                $category->loads([
                    'user_id' => $this->id,
                    'type' => $type,
                    'category_id' => $id,
                ]);
                $category->save();
            }
        }
        if( ! empty($userCategories)) {
            UserCategory::deleteAll(['id' => ArrayHelper::getColumn($userCategories, 'id')]);
        }
        return true;
    }
    
    /**
     * 搜索设计师
     * @return boolean|array
     */
    public static function search($condition = [])
    {
        $search = static::find()->where(['role' => static::RoleDesigner, 'status' => static::StatusActive, 'bond_status' => [static::BondStatusMoney, static::BondStatusAlipay]]);
        $tab = [
            'category_id' => [UserCategory::TypeCategory, 'ctt'],
            'model' => [UserCategory::TypeModel, 'mdt'],
            'style' => [UserCategory::TypeStyle, 'stt'],
        ];
        foreach($tab as $key => $detail) {
            if(isset($condition[$key]) && strlen($condition[$key]) > 0) {
                $search->leftJoin(UserCategory::tableName().' as '.$detail[1], [
                    $detail[1].'.user_id' => new Expression(static::tableName().'.id'),
                    $detail[1].'.type' => $detail[0],
                    $detail[1].'.category_id' => $condition[$key]
                ])->andWhere(['>=', $detail[1].'.id', 0]);
                unset($condition[$key]);
            }
        }
        $search->andFilterWhere(static::initCondition(['level'], $condition));
        return $search;
    }

    /**
     * 等级认证后需要交纳保证金
     * $bond  保证金 金额
     */
    public function paydeposit($user){
        //获取用户bond_status 保证金状态  alipay_score 芝麻信用分 level 等级

        $alipay_score = $user['alipay_score'];
        $level = $user['level'];
//        if($user['bond_status'] == 0 && $alipay_score >= 700){
//            switch ($level)
//            {
//                case "0":
//                    $bond = 500;
//                    break;
//                case "1":
//                    $bond = 1500;
//                    break;
//                case "2":
//                    $bond = 2500;
//                    break;
//                case "3":
//                    $bond = 3500;
//                    break;
//                case "4":
//                    $bond = 6500;
//                    break;
//            }
//
//        }else{
//            switch ($level)
//            {
//                case "0":
//                    $bond = 3500;
//                    break;
//                case "1":
//                    $bond = 4500;
//                    break;
//                case "2":
//                    $bond = 5500;
//                    break;
//                case "3":
//                    $bond = 6500;
//                    break;
//                case "4":
//                    $bond = 9500;
//                    break;
//            }
//        }
        if($user['bond_status'] == 0 && $alipay_score >= 700){
            switch ($level)
            {
                case "0":
                    $bond = 1;
                    break;
                case "1":
                    $bond = 2;
                    break;
                case "2":
                    $bond = 3;
                    break;
                case "3":
                    $bond = 4;
                    break;
                case "4":
                    $bond = 5;
                    break;
            }

        }else{
            switch ($level)
            {
                case "0":
                    $bond = 2;
                    break;
                case "1":
                    $bond = 4;
                    break;
                case "2":
                    $bond = 6;
                    break;
                case "3":
                    $bond = 8;
                    break;
                case "4":
                    $bond = 10;
                    break;
            }
        }
        return $bond;
    }

    /**
     * 拼接邀请码地址
     */
    public function invitingcode(){

        $invitingcode = 'http';

        if ($_SERVER["HTTPS"] == "on")
        {
            $invitingcode .= "s";
        }
        $invitingcode .= "://";
        $inviter = $this->id;
        if ($_SERVER["SERVER_PORT"] != "80")
        {
            $invitingcode .= $_SERVER["SERVER_NAME"] . "/" . "user/register?inviter=".$inviter;
        }
        else
        {
            $invitingcode .= $_SERVER["SERVER_NAME"] . "/user/register?inviter=".$inviter;
        }
//        http://www.17yixi.com/user/register?inviter=用户编号
        return $invitingcode;
    }
}